using System.Collections;
using System.Collections.Generic;
using System.Text;
using GPUAnimationLib.Runtime;
using Unity.Mathematics;
using UnityEngine;

namespace GPUAnimationLib.Baker
{
    public static class AttachmentBakerApi
    {
        public static (GPUAttachmentData[], AttachmentAnchorData) BakeAttachmentAnchorData(GameObject sourceGo, Animator animator, GPUAnimationBaker.Data bakerData, GPUAnimationData[] animationDatas, int totalFrames)
        {
            if (bakerData.AttachmentDatas == null || bakerData.AttachmentDatas.Length == 0) return (null, null);
            int attachmentCount = bakerData.AttachmentDatas.Length;
            GPUAttachmentData[] gpuAttachmentDatas = new GPUAttachmentData[attachmentCount];
            AttachmentAnchorData attachmentAnchorData = ScriptableObject.CreateInstance<AttachmentAnchorData>();
            attachmentAnchorData.AnchorTransforms = new Matrix4x4[attachmentCount * totalFrames];
            
            for (int attachmentAnchorIndex = 0; attachmentAnchorIndex < attachmentCount; attachmentAnchorIndex++)
            {
                var attachmentData = bakerData.AttachmentDatas[attachmentAnchorIndex];
                gpuAttachmentDatas[attachmentAnchorIndex] = new GPUAttachmentData()
                {
                    Attachment = attachmentData.Attachment,
                };
                Transform attachmentTransform = sourceGo.transform.Find(GetTransformPath(attachmentData.Transform));
                int baseIndex = attachmentAnchorIndex * totalFrames;
                GPUAnimationBakerApi.IterateOverAllFramesThroughAnimator(animator, bakerData, animationDatas,
                    (currentFrameIndex) =>
                    {
                        attachmentAnchorData.AnchorTransforms[baseIndex + currentFrameIndex] = attachmentTransform.localToWorldMatrix;
                    });
            }
            return (gpuAttachmentDatas, attachmentAnchorData);
        }
        
        static string GetTransformPath(Transform transform)
        {
            void FillTrans(Transform currentTransform, List<Transform> transforms)
            {
                if (currentTransform == null) return;
                transforms.Add(currentTransform);
                currentTransform = currentTransform.parent;
                FillTrans(currentTransform, transforms);
            }
            List<Transform> transforms = new List<Transform>();
            FillTrans(transform, transforms);
            transforms.RemoveAt(transforms.Count - 1);
            StringBuilder sb = new StringBuilder();
            for (int i = transforms.Count - 1; i >= 0; i--)
            {
                sb.Append(transforms[i].name);
                sb.Append("/");
            }
            var path = sb.ToString();
            path = path.Remove(path.Length - 1);
            //Debug.Log(path);
            return path;
        }
    }
}